home *** CD-ROM | disk | FTP | other *** search
- /* convers server - based on conversd written by DK5SG
- * ported to WNOS by DB3FL - 9109xx/9110xx
- *
- * Ported to NOS and many mods and bug fixes by SM6RPZ
- * 1992-01-10 - 1992-04-09 No history. Some fixes taken from PE1NMB and PA0GRI.
- * 1992-04-09 - Added prototypes to all functions.
- * 1992-04-12 - Added L:s in timestring() It used 32767 as seconds
- * per day before :-) Also added L:s on other places.
- * 1992-07-09 - Changes inspired by WNOS ver 4a8
- * - Changed all arrays in struct convection and struct permlink
- * to pointers.
- * - Added getarg() and changed some functions to use it.
- * - Raised stacksize on cperm from 1024 to 2048.
- * - Myhostname changed to Hostname and hostname not needed anymore
- * in converse.cfg
- * - Some small fixes here and there.
- * 1992-07-11 - SOBUF changed from 256 to 2048 in usock.h to make us able
- * to use 2048 bytes in our buffers.
- * 1992-07-18 - There's no reason to run in the permlink loop if we don't have
- * any links. A check for this is made (idea from WG7J ver 1.03).
- * Imported into AmigaNos by oz1dti. Thanks Lars!
- */
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- #ifdef UNIX
- #include <sys/types.h>
- #include <sys/stat.h>
- #endif
- #ifndef AMIGA
- #include <io.h>
- #endif
- #include "global.h"
- #include "config.h"
- #ifdef CHATNODE
- #ifdef MAILBOX
- #include "mailbox.h"
- #include "netuser.h"
- #endif
- #include "timer.h"
- #include "cmdparse.h"
- #include "socket.h"
- #include "session.h"
- #include "files.h"
- #include "commands.h"
-
- static struct convection *convections; /* Not Used in mailbox.c */
-
- #define LINK 1 /* Start LINK -- SM6RPZ */
-
- #define MAXCHANNEL 32767
- #define LINELEN 256
- #define CBUFLEN 2048
- #define MAX_WAITTIME (60L*60L*3L)
-
- struct convection {
- int type; /* Connection type */
- #define CT_UNKNOWN 0
- #define CT_USER 1
- #define CT_HOST 2
- #define CT_CLOSED 3
- char *name; /* Name of user or host */
- char *host; /* Name of host where user is logged on */
- struct convection *via; /* Pointer to neighbor host */
- int channel; /* Channel number */
- int32 time; /* Connect time */
- int locked; /* Set if mesg already sent */
- int fd; /* Socket descriptor */
- int fmask; /* Socket mask */
- char *ibuf; /* Input buffer */
- int received; /* Number of bytes received */
- int xmitted; /* Number of bytes transmitted */
- struct convection *next; /* Linked list pointer */
- };
- #define NULLCONNECTION ((struct convection *) 0)
-
- #define CM_UNKNOWN (1 << CT_UNKNOWN)
- #define CM_USER (1 << CT_USER)
- #define CM_HOST (1 << CT_HOST)
- #define CM_CLOSED (1 << CT_CLOSED)
-
- /* in convers.c */
- static struct convection *convections; /* Not Used in mailbox.c */
- static char *timestring __ARGS((long gmt)); /* Not Used in mailbox.c */
-
-
- struct permlink {
- char *name; /* Name of host */
- char *link_info; /* Name of socket to connect to */
- char *command; /* Optional connect command */
- struct convection *convection;/* Pointer to associated connection */
- int32 statetime; /* Time of last (dis)connect */
- int tries; /* Number of connect tries */
- int32 waittime; /* Time between connect tries */
- int32 retrytime; /* Time of next connect try */
- int fd; /* socket descriptor */
- struct permlink *next; /* Linked list pointer */
- };
- #define NULLPERMLINK ((struct permlink *) 0)
-
- static struct permlink *permlinks;
- static int Sconv = -1;
- static int Inlink = 0; /* links acceptance -oz1dti*/
-
- static void free_connection __ARGS((register struct convection *cp));
- static void free_closed_connections __ARGS((void));
- static void update_permlinks __ARGS((char *name,struct convection *cp));
- static struct convection *alloc_connection __ARGS((int fd));
- static char *getarg __ARGS((char *line, int all));
- #ifdef LINK
- static char links = 0;
- static void connect_permlinks __ARGS((int a,void *b,void *c));
- #endif
- static void clear_locks __ARGS((void));
- static void send_user_change_msg __ARGS((char *name,char *host,int oldchannel,int newchannel));
- static char *formatline __ARGS((char *prefix,char *text));
- static void send_msg_to_user __ARGS((char *fromname,char *toname,char *text));
- static void send_msg_to_channel __ARGS((char *fromname,int channel,char *text));
- static void send_invite_msg __ARGS((char *fromname,char *toname,int channel));
- static void bye_command __ARGS((struct convection *cp));
- static void channel_command __ARGS((struct convection *cp));
- static void help_command __ARGS((struct convection *cp));
- static void invite_command __ARGS((struct convection *cp));
- static void links_command __ARGS((struct convection *cp));
- static void msg_command __ARGS((struct convection *cp));
- static void name_command __ARGS((struct convection *cp));
- static void who_command __ARGS((struct convection *cp));
- static void h_cmsg_command __ARGS((struct convection *cp));
- static void h_host_command __ARGS((struct convection *cp));
- static void h_invi_command __ARGS((struct convection *cp));
- static void h_loop_command __ARGS((struct convection *cp));
- static void h_umsg_command __ARGS((struct convection *cp));
- static void h_user_command __ARGS((struct convection *cp));
- static void conv_incom __ARGS((int s,void *t,void *p));
-
- /* Stop convers server */
- int
- conv0(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- close_s(Sconv);
- Sconv = -1;
- return 0;
- }
-
- /* Start up convers server */
- int
- conv1(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct sockaddr_in lsocket;
- int s;
- #ifdef LINK
- struct proc *child;
- #endif
-
- if(Sconv != -1)
- return 0;
-
- psignal(Curproc,0); /* Don't keep the parser waiting */
- chname(Curproc,"Chatnode listener");
-
- lsocket.sin_family = AF_INET;
- lsocket.sin_addr.s_addr = INADDR_ANY;
- lsocket.sin_port = (argc < 2) ? IPPORT_CHATNODE : atoi(argv[1]);
-
- Sconv = socket(AF_INET,SOCK_STREAM,0);
- bind(Sconv,(char *)&lsocket,sizeof(lsocket));
- if(listen(Sconv,1) == -1) {
- close_s(Sconv);
- Sconv = -1;
- return 0;
- }
- #ifdef LINK
- child = newproc("cperm",2048,connect_permlinks,0,0,NULL);
- #endif
- for(;;) {
- if((s = accept(Sconv,NULLCHAR,(int *)NULL)) == -1)
- break; /* Service is shutting down */
- if(availmem() < Memthresh + 16384L)
- shutdown(s,1); /* Not enough memory */
- else
- newproc("chatnode",2048,conv_incom,s,0,NULL);/* Spawn a server */
- }
- #ifdef LINK
- if(links)
- killproc(child);
- #endif
- close_s(Sconv);
- Sconv = -1;
- return 0;
- }
-
- static char *
- getarg(line,all)
- char *line;
- int all;
- {
- char *arg;
- int c;
- static char *p;
-
- if(line)
- p = line;
- while(isspace(uchar(*p)))
- p++;
- if(all)
- return p;
- arg = p;
- while(*p && !isspace(uchar(*p))) {
- c = tolower(uchar(*p));
- *p++ = c;
- }
- if(*p)
- *p++ = '\0';
- return arg;
- }
-
- static void
- free_connection(cp)
- register struct convection *cp;
- {
- register struct permlink *p;
-
- for(p = permlinks; p; p = p->next)
- if(p->convection == cp)
- p->convection = NULLCONNECTION;
- if(cp->fmask)
- close_s(cp->fd);
- free(cp->name);
- free(cp->host);
- free(cp->ibuf);
- free((char *) cp);
- }
-
- static void
- free_closed_connections()
- {
- register struct convection *cp,*p;
- time_t currtime;
-
- for(p = NULLCONNECTION,cp = convections; cp; )
- if(cp->type == CT_CLOSED ||
- cp->type == CT_UNKNOWN && cp->time + 300L < time(&currtime)) {
- if(p) {
- p->next = cp->next;
- free_connection(cp);
- cp = p->next;
- } else {
- convections = cp->next;
- free_connection(cp);
- cp = convections;
- }
- } else {
- p = cp;
- cp = cp->next;
- }
- }
-
- static void
- update_permlinks(name,cp)
- char *name;
- struct convection *cp;
- {
- register struct permlink *p;
- time_t currtime;
-
- for(p = permlinks; p; p = p->next)
- if(!strcmp(p->name,name)) {
- p->convection = cp;
- p->statetime = time(&currtime);
- p->tries = 0;
- p->waittime = 60L;
- p->retrytime = currtime + p->waittime;
- }
- }
-
- static struct convection *
- alloc_connection(fd)
- int fd;
- {
- register struct convection *cp;
- time_t currtime;
-
- cp = (struct convection *)callocw(1,sizeof(struct convection));
- cp->name = NULLCHAR;
- cp->host = NULLCHAR;
- cp->time = time(&currtime);
- cp->fd = cp->fmask = fd;
- cp->ibuf = mallocw(CBUFLEN+1);
- cp->next = convections;
- convections = cp;
- return cp;
- }
-
- #ifdef LINK
- static void
- connect_permlinks(a,b,c)
- int a;
- void *b;
- void *c;
- {
- int s,len = SOCKSIZE;
- register struct permlink *p;
- struct sockaddr_in cport;
- FILE *fp;
- char *host_name, *link_info, *command, line[LINELEN];
- time_t currtime;
-
- if((fp = fopen(Chatnode,"r")) != NULLFILE) {
- Inlink = 1; /* linkrequests will be accepted -oz1dti */
- while(fgets(line,LINELEN,fp)) {
- rip(line);
- if(*line == '#' || *line == '\0')
- continue;
- host_name = getarg(line,0);
- link_info = getarg(0,0);
- command = getarg(0,0);
- if(host_name != NULLCHAR && link_info != NULLCHAR) {
- p = (struct permlink *)callocw(1,sizeof(struct permlink ));
- p->name = strdup(host_name);
- p->link_info = strdup(link_info);
- if(command != NULLCHAR)
- p->command = strdup(command);
- p->next = permlinks;
- permlinks = p;
- update_permlinks(host_name,NULLCONNECTION);
- }
- }
- fclose(fp);
- }
-
- /* If the're no links, there's no reason to stay alive - WG7J */
- if(permlinks == NULLPERMLINK)
- return;
-
- links = 1; /* This process has to be killed */
-
- for(;;) {
- pause(1000L);
- for(p = permlinks; p; p = p->next) {
- if(p->convection || p->retrytime > time(&currtime))
- continue;
- p->tries++;
- p->waittime <<= 1;
- if(p->waittime > MAX_WAITTIME)
- p->waittime = MAX_WAITTIME;
- p->retrytime = p->waittime + currtime;
- switch(tolower(*p->link_info)) {
- case 't': /* telnet connection */
- cport.sin_family = AF_INET;
- cport.sin_port = IPPORT_CHATNODE;
- if((cport.sin_addr.s_addr = resolve(p->name)) == 0)
- continue;
- if((s = socket(AF_INET,SOCK_STREAM,0)) == -1)
- continue;
- mainlog(s,"PERMLINK trying %s",p->name);
- if(connect(s,(char *)&cport,len) == -1) {
- mainlog(s,"PERMLINK reset received from %s",p->name);
- close_s(s);
- continue;
- }
- mainlog(s,"PERMLINK connected to %s",p->name);
- break;
- #ifdef notdef /* Not implemented yet! */
- case 'a': /* ax25 connection */
- case 'n': /* netrom connection */
- #endif
- default:
- continue;
- }
- p->fd = s;
- newproc("permlink",1024,conv_incom,s,0,NULL);
- }
- }
- }
- #endif
-
- static void
- clear_locks()
- {
- register struct convection *p;
-
- for(p = convections; p; p = p->next)
- p->locked = 0;
- }
-
- static void
- send_user_change_msg(name,host,oldchannel,newchannel)
- char *name,*host;
- int oldchannel,newchannel;
- {
- register struct convection *p;
-
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER && !p->via && !p->locked) {
- if(p->channel == oldchannel) {
- if(newchannel >= 0)
- p->xmitted += usprintf(p->fd,
- "*** %s switched to channel %d.\n",name,newchannel);
- else
- p->xmitted += usprintf(p->fd,"*** %s signed off.\n",name);
- p->locked = 1;
- }
- if(p->channel == newchannel) {
- p->xmitted += usprintf(p->fd,"\007\007*** %s signed on.\n",name);
- p->locked = 1;
- }
- }
- if(p->type == CT_HOST && !p->locked) {
- p->xmitted += usprintf(p->fd,"/\377\200USER %s %s 0 %d %d\n",
- name,host,oldchannel,newchannel);
- p->locked = 1;
- }
- }
- return;
- }
-
- static char *
- formatline(prefix,text)
- char *prefix,*text;
- {
- #define PREFIXLEN 10
- #define CONVLINELEN 79
- register char *f, *t, *x;
- register int l, lw;
- static char buf[CBUFLEN];
-
- for(f = prefix,t = buf; *f; *t++ = *f++)
- ;
- l = (int)(t - buf);
- f = text;
-
- for(;;) {
- while(isspace(uchar(*f)))
- f++;
- if(!*f) {
- *t++ = '\n';
- *t = '\0';
- return buf;
- }
- for(x = f; *x && !isspace(uchar(*x)); x++)
- ;
- lw = (int)(x - f);
- if(l > PREFIXLEN && l + 1 + lw > CONVLINELEN) {
- *t++ = '\n';
- l = 0;
- }
- do {
- *t++ = ' ';
- l++;
- } while(l < PREFIXLEN);
- while(lw--) {
- *t++ = *f++;
- l++;
- }
- }
- }
-
- static void
- send_msg_to_user(fromname,toname,text)
- char *fromname,*toname,*text;
- {
- register struct convection *p;
- char *buffer = mallocw(CBUFLEN+1);
-
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER && !strcmp(p->name,toname))
- if(p->via) {
- if(!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200UMSG %s %s %s",fromname,toname,text);
- p->via->locked = 1;
- }
- } else {
- if(!p->locked) {
- if(strcmp(fromname,"chatnode")) {
- sprintf(buffer,"<*%s*>:",fromname);
- p->xmitted += usprintf(p->fd,"%s",
- formatline(buffer,text));
- } else
- p->xmitted += usprintf(p->fd,"%s\n",text);
- p->locked = 1;
- }
- }
- }
- free(buffer);
- return;
- }
-
- static void
- send_msg_to_channel(fromname,channel,text)
- char *fromname;
- int channel;
- char *text;
- {
- char *buffer = mallocw(CBUFLEN+1);
- register struct convection *p;
-
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER && p->channel == channel)
- if(p->via) {
- if(!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200CMSG %s %d %s\n",fromname,channel,text);
- p->via->locked = 1;
- }
- } else {
- if(!p->locked) {
- sprintf(buffer,"<%s>:",fromname);
- /* p->xmitted += usprintf(p->fd,"%s",formatline(&buffer[0],text));*/
- p->xmitted += usprintf(p->fd,"%s",formatline(buffer,text));
- p->locked = 1;
- }
- }
- }
- free(buffer);
- return;
- }
-
- char *
- timestring(gmt) /* used in mailbox.c */
- long gmt;
- {
- static char buffer[10];
- struct tm *tm;
- time_t currtime;
- extern char *Months[]; /* in smtpserv.c */
-
- tm = localtime(&gmt);
- if(gmt + 24L * 60L * 60L > time(&currtime))
- sprintf(buffer," %2d:%02d",tm->tm_hour,tm->tm_min);
- else
- sprintf(buffer,"%-3.3s %2d",Months[tm->tm_mon],tm->tm_mday);
- return buffer;
- }
-
- static void
- send_invite_msg(fromname,toname,channel)
- char *fromname,*toname;
- int channel;
- {
- char invitetext[] = "\n\007\007*** Message from %s at%s ...\nPlease join chatnode channel %d.\n\007\007\n";
- char mbinvitetext[] = "\n\007\007*** Message from %s at%s ...\nPlease type 'C' to join chatnode, then goto channel %d.\n\007\007\n";
- char responsetext[] = "*** Invitation sent to %s @ %s";
- char cnvd[] = "chatnode";
- char *buffer = mallocw(CBUFLEN+1);
- register struct convection *p;
- time_t currtime;
- #ifdef MAILBOX
- int i;
- struct mbx *m;
- #endif
-
- currtime = time(&currtime);
- for(p = convections; p; p = p->next) {
- #ifdef MAILBOX
- for(i = 0; i < NUMMBX; i++){
- if((m = Mbox[i]) != NULLMBX){
- if(m->state == MBX_CMD && !strcmp(m->name,toname)) {
- p->xmitted += usprintf(m->user,mbinvitetext,fromname,timestring(currtime),channel);
- usflush(m->user);
- clear_locks();
- sprintf(buffer,responsetext,toname,"LocBBS@");
- strcat(buffer,Hostname);
- send_msg_to_user(cnvd,fromname,buffer);
- free(buffer);
- return;
- }
- }
- }
- #endif
- if(p->type == CT_USER && !strcmp(p->name,toname)) {
- if(p->channel == channel) {
- clear_locks();
- sprintf(buffer,"*** User %s is already on this channel.",toname);
- send_msg_to_user(cnvd,fromname,buffer);
- free(buffer);
- return;
- }
- if(!p->via && !p->locked) {
- p->xmitted += usprintf(p->fd,invitetext,fromname,timestring(currtime),channel);
- clear_locks();
- sprintf(buffer,responsetext,toname,Hostname);
- send_msg_to_user(cnvd,fromname,buffer);
- free(buffer);
- return;
- }
- if(p->via && !p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200INVI %s %s %d\n",fromname,toname,channel);
- free(buffer);
- return;
- }
- }
- if(p->type == CT_HOST && !p->locked) {
- p->xmitted += usprintf(p->fd,"/\377\200INVI %s %s %d\n",fromname,toname,channel);
- free(buffer);
- return;
- }
- }
- free(buffer);
- return;
- }
-
- static void
- bye_command(cp)
- struct convection *cp;
- {
- register struct convection *p;
-
- if(cp->type != CT_CLOSED)
- mainlog(cp->fd,"close CHATNODE");
- switch(cp->type) {
- case CT_UNKNOWN:
- cp->type = CT_CLOSED;
- break;
- case CT_USER:
- cp->type = CT_CLOSED;
- clear_locks();
- send_user_change_msg(cp->name,cp->host,cp->channel,-1);
- break;
- case CT_HOST:
- cp->type = CT_CLOSED;
- update_permlinks(cp->name,NULLCONNECTION);
- for(p = convections; p; p = p->next)
- if(p->via == cp) {
- p->type = CT_CLOSED;
- clear_locks();
- send_user_change_msg(p->name,p->host,p->channel,-1);
- }
- break;
- case CT_CLOSED:
- break;
- }
- }
-
- static void
- channel_command(cp)
- struct convection *cp;
- {
- int newchannel;
- char *s = getarg(0,0);
-
- if(!*s) {
- cp->xmitted += usprintf(cp->fd,"*** You are on channel %d.\n",cp->channel);
- return;
- }
- newchannel = atoi(s);
- if(newchannel < 0 || newchannel > MAXCHANNEL) {
- cp->xmitted += usprintf(cp->fd,
- "*** Channel numbers must be in the range 0..%d.\n",MAXCHANNEL);
- return;
- }
- if(newchannel == cp->channel) {
- cp->xmitted += usprintf(cp->fd,"*** Already on channel %d.\n",cp->channel);
- return;
- }
- send_user_change_msg(cp->name,cp->host,cp->channel,newchannel);
- cp->channel = newchannel;
- cp->xmitted += usprintf(cp->fd,"*** Now on channel %d.\n",cp->channel);
- return;
- }
-
- static void
- help_command(cp)
- struct convection *cp;
- {
- cp->xmitted += usprintf(cp->fd,"Commands may be abbreviated. Commands are:\n");
- cp->xmitted += usprintf(cp->fd,"/? or /help Print help information\n");
- cp->xmitted += usprintf(cp->fd,"/bye Terminate the chatnode session\n");
- cp->xmitted += usprintf(cp->fd,"/channel <n> Switch to channel n\n");
- cp->xmitted += usprintf(cp->fd,"/exit Terminate the chatnode session\n");
- cp->xmitted += usprintf(cp->fd,"/invite <user> Invite user to join your channel\n");
- cp->xmitted += usprintf(cp->fd,"/links [long] List all connections to other hosts\n");
- cp->xmitted += usprintf(cp->fd,"/msg <user> text... Send a private message to user\n");
- cp->xmitted += usprintf(cp->fd,"/quit Terminate the chatnode session\n");
- cp->xmitted += usprintf(cp->fd,"/who [quick] [long] List all users and their channel numbers\n");
- cp->xmitted += usprintf(cp->fd,"/write <user> text... Send a private message to user\n***\n");
- return;
- }
-
- static void
- invite_command(cp)
- struct convection *cp;
- {
- char *toname = getarg(0,0);
-
- if(*toname)
- send_invite_msg(cp->name,toname,cp->channel);
- return;
- }
-
- static void
- links_command(cp)
- struct convection *cp;
- {
- register struct convection *pc;
- register struct permlink *pp;
- char tmp[20];
- char full = *(getarg(0,0));
-
- cp->xmitted += usprintf(cp->fd,"Host State Since%s\n",
- full ? " NextTry Tries Receivd Xmitted" : "");
- for(pc = convections; pc; pc = pc->next)
- if(pc->type == CT_HOST) {
- cp->xmitted += usprintf(cp->fd,
- full ?
- "%-15.15s %-12s %s %7d %7d\n" :
- "%-15.15s %-12s %s\n",
- pc->name,
- "Connected",
- timestring(pc->time),
- pc->received,
- pc->xmitted);
- }
- for(pp = permlinks; pp; pp = pp->next)
- if(!pp->convection || pp->convection->type != CT_HOST) {
- strcpy(tmp,timestring(pp->retrytime));
- cp->xmitted += usprintf(cp->fd,
- full ?
- "%-15.15s %-12s %s %s %5d\n" :
- "%-15.15s %-12s %s\n",
- pp->name,
- pp->convection ? "Connecting" : "Disconnected",
- timestring(pp->statetime),
- tmp,
- pp->tries);
- }
- cp->xmitted += usprintf(cp->fd,"***\n");
- return;
- }
-
- static void
- msg_command(cp)
- struct convection *cp;
- {
- register struct convection *p;
- char *toname = getarg(0,0);
- char *text = getarg(0,1);
-
- if(!*text)
- return;
- for(p = convections; p; p = p->next)
- if(p->type == CT_USER && !strcmp(p->name,toname))
- break;
- if(!p)
- cp->xmitted += usprintf(cp->fd,"*** No such user: %s.\n",toname);
- else
- send_msg_to_user(cp->name,toname,text);
- return;
- }
-
- static void
- name_command(cp)
- struct convection *cp;
- {
- int newchannel;
- char *s = getarg(0,0);
-
- if(!*s)
- return;
- cp->name = strdup(s);
- strlwr(cp->name);
- cp->host = strdup(Hostname);
- cp->type = CT_USER;
- cp->xmitted += usprintf(cp->fd,
- "*** Welcome to the %s Conference System. Type /? for help ***\n",Hostname);
- newchannel = atoi(getarg(0,0));
- if(newchannel < 0 || newchannel > MAXCHANNEL)
- cp->xmitted += usprintf(cp->fd,
- "*** Channel numbers must be in the range 0..%d.\n",MAXCHANNEL);
- else
- cp->channel = newchannel;
- mainlog(cp->fd,"CHATNODE login: %s",cp->name);
- send_user_change_msg(cp->name,cp->host,-1,cp->channel);
- return;
- }
-
- static void
- who_command(cp)
- struct convection *cp;
- {
- int channel,full = 0,quick = 0;
- register struct convection *p;
- #ifdef MAILBOX
- int i;
- struct mbx *m;
- #endif
- char *buffer = mallocw(CBUFLEN+1);
-
- switch(*(getarg(0,0))) {
- case 'l':
- full = 1;
- break;
- case 'q':
- quick = 1;
- break;
- }
-
- if(quick) {
- cp->xmitted += usprintf(cp->fd,"Channel Users\n");
- clear_locks();
- do {
- channel = -1;
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER && !p->locked &&
- (channel < 0 || channel == p->channel)) {
- if(channel < 0) {
- channel = p->channel;
- sprintf(buffer,"%7d",channel);
- }
- strcat(buffer," ");
- strcat(buffer,p->name);
- p->locked = 1;
- }
- }
- if(channel >= 0) {
- cp->xmitted += usprintf(cp->fd,"%s\n",buffer);
- }
- } while(channel >= 0);
- } else {
- cp->xmitted += usprintf(cp->fd,
- "User Host Via Channel Since%s\n",
- full ? " Receivd Xmitted" : "");
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER) {
- cp->xmitted += usprintf(cp->fd,
- full ?
- "%-8.8s %-15.15s %-15.15s %7d %s %7d %7d\n" :
- "%-8.8s %-15.15s %-15.15s %7d %s\n",
- p->name,
- p->host,
- p->via ? p->via->name : "",
- p->channel,
- timestring(p->time),
- p->received,
- p->xmitted);
- }
- }
- }
- #ifdef MAILBOX
- for(i = 0; i < NUMMBX; i++)
- if((m = Mbox[i]) != NULLMBX)
- if(m->state == MBX_CMD)
- if(quick)
- cp->xmitted += usprintf(cp->fd," LocBBS %s\n",m->name);
- else
- cp->xmitted += usprintf(cp->fd,"%-8s LocBBS@%s\n",m->name,Hostname);
- #endif
- cp->xmitted += usprintf(cp->fd,"***\n");
- free(buffer);
- return;
- }
-
- static void
- h_cmsg_command(cp)
- struct convection *cp;
- {
- char *name = getarg(0,0);
- int channel = atoi(getarg(0,0));
- char *text = getarg(0,1);
-
- if(*text)
- send_msg_to_channel(name, channel, text);
- }
-
- static void
- h_host_command(cp)
- struct convection *cp;
- {
- register struct convection *p;
- register struct permlink *pp;
- char *name = getarg(0,0);
-
- if(!*name)
- return;
- for(p = convections; p; p = p->next)
- if(!strcmp(p->name,name))
- bye_command(p);
- for(pp = permlinks; pp; pp = pp->next)
- if(!strcmp(pp->name,name) && pp->convection && pp->convection != cp)
- bye_command((strcmp(Hostname,name) < 0) ? pp->convection : cp);
- if(cp->type != CT_UNKNOWN)
- return;
- if(Inlink != 1) /* link acceptance -oz1dti*/
- return;
- cp->type = CT_HOST;
- cp->name = strdup(name);
- update_permlinks(name,cp);
- cp->xmitted += usprintf(cp->fd,"/\377\200HOST %s\n",Hostname);
- for(p = convections; p; p = p->next)
- if(p->type == CT_USER)
- cp->xmitted += usprintf(cp->fd,
- "/\377\200USER %s %s 0 -1 %d\n",p->name,p->host,p->channel);
- mainlog(cp->fd,"PERMLINK login: %s",cp->name);
- return;
- }
-
- static void
- h_invi_command(cp)
- struct convection *cp;
- {
- char *fromname = getarg(0,0);
- char *toname = getarg(0,0);
- int channel = atoi(getarg(0,0));
-
- send_invite_msg(fromname, toname, channel);
- }
-
- static void
- h_loop_command(cp)
- struct convection *cp;
- {
- char *host = getarg(0,0);
-
- mainlog(cp->fd, "chatnode rx: LOOP %s",host);
- bye_command(cp);
- }
-
- static void
- h_umsg_command(cp)
- struct convection *cp;
- {
- char *fromname = getarg(0,0);
- char *toname = getarg(0,0);
- char *text = getarg(0,1);
-
- if(*text)
- send_msg_to_user(fromname, toname, text);
- }
-
- static void
- h_user_command(cp)
- struct convection *cp;
- {
- int oldchannel, newchannel;
- register struct convection *p;
- time_t currtime;
- char *name = getarg(0,0);
- char *host = getarg(0,0);
- getarg(0,0); /* ignore this argument, protocol has changed */
- oldchannel = atoi(getarg(0,0));
- newchannel = atoi(getarg(0,0));
-
- for(p = convections; p; p = p->next)
- if(p->type == CT_USER) {
- /* new 920705 dl9sau */
- /* If Neighbour2 registers a user on HostX, while someone has already
- * been registered for HostX via Neighbour1, then we definitely have
- * a loop ! We send a loop detect message and then close the link:
- * /..LOOP <myhostname> <myneighbour> <host>
- *
- * The LOOP PREVENTION CODE detects ONLY a loop if it starts at this
- * host. That's, why I suggest this code to be implemented in every
- * conversd implementation.
- */
- if (oldchannel < 0 && p->via != cp && !strcmp(p->host, host)) {
- usprintf(cp->fd,"/\377\200LOOP %s %s %s\n",
- Hostname, host,p->via ? p->via->name : Hostname);
- mainlog(cp->fd, "chatnode sent: LOOP %s",host);
- bye_command(cp);
- return;
- }
- if(p->channel == oldchannel &&
- p->via == cp &&
- !strcmp(p->name,name) &&
- !strcmp(p->host,host))
- break;
- }
- if(!p) {
- p = (struct convection *)callocw(1,sizeof(struct convection));
- p->type = CT_USER;
- p->name = strdup(name);
- p->host = strdup(host);
- p->via = cp;
- p->channel = oldchannel;
- p->time = time(&currtime);
- p->next = convections;
- convections = p;
- }
- if((p->channel = newchannel) < 0)
- p->type = CT_CLOSED;
- send_user_change_msg(name,host,oldchannel,newchannel);
- if(oldchannel == -1)
- mainlog(p->fd,"CHATNODE login: %s host: %s",p->name,p->host);
- if(newchannel == -1)
- mainlog(p->fd,"CHATNODE logout: %s host: %s",p->name,p->host);
- return;
- }
-
- /* Incoming convers session */
- static void
- conv_incom(s,t,p)
- int s;
- void *t;
- void *p;
- {
- int arglen,size;
- char permlink = 0;
- register struct convection *cp;
- register struct permlink *pl;
- char *arg,*ccp,*cccp;
- #ifdef MAILBOX
- int len;
- char fsocket[MAXSOCKSIZE];
- #endif
- static struct cmdtable {
- char *name;
- void (*fnc) __ARGS((struct convection *cp)); /* decl added -oz1dti */
- int states;
- } cmdtable[] = {
- "?", help_command, CM_USER,
- "bye", bye_command, CM_USER,
- "channel", channel_command, CM_USER,
- "exit", bye_command, CM_USER,
- "help", help_command, CM_USER,
- "invite", invite_command, CM_USER,
- "links", links_command, CM_USER,
- "msg", msg_command, CM_USER,
- "name", name_command, CM_UNKNOWN,
- "quit", bye_command, CM_USER,
- "who", who_command, CM_USER,
- "write", msg_command, CM_USER,
-
- "\377\200cmsg", h_cmsg_command, CM_HOST,
- "\377\200host", h_host_command, CM_UNKNOWN,
- "\377\200loop", h_loop_command, CM_HOST,
- "\377\200invi", h_invi_command, CM_HOST,
- "\377\200umsg", h_umsg_command, CM_HOST,
- "\377\200user", h_user_command, CM_HOST,
- 0, 0, 0,
- };
- struct cmdtable *cmdp;
-
- sockowner(s,Curproc); /* We own it now */
- /* sockmode(s,SOCK_BINARY); Not in current version -oz1dti */
- cp = alloc_connection(s);
- mainlog(cp->fd,"open CHATNODE");
-
- for(pl = permlinks; pl; pl = pl->next)
- if(pl->fd == s) {
- permlink = 1;
- pl->convection = cp;
- if(pl->command != NULLCHAR)
- usprintf(s,"%s",pl->command);
- cp->xmitted += usprintf(s,"/\377\200HOST %s\n",Hostname);
- }
-
- if(!permlink) {
- #ifdef MAILBOX
- getpeername(s,fsocket,&len);
- ccp = strdup(psocket(fsocket));
- if((cccp = strchr(ccp,':')) != NULLCHAR)
- *cccp = '\0';
- if(strcmp(ccp,inet_ntoa(Ip_addr)) != 0)
- #endif
- usprintf(cp->fd,"pse login with '/n <call>'\n");
- #ifdef MAILBOX
- free(ccp); /* have to be free()d */
- #endif
- }
-
- for(;;) {
- loop:
- if(cp->type == CT_CLOSED)
- break;
- if((size = recvline(cp->fd,cp->ibuf,CBUFLEN)) <= 0)
- break;
- cp->received += size;
- clear_locks();
- cp->locked = 1;
- if((ccp = strpbrk(cp->ibuf,"\r\n")) != NULLCHAR)
- *ccp = '\0';
- if(*cp->ibuf == '/') {
- arglen = strlen(arg = getarg(cp->ibuf + 1,0));
- for(cmdp = cmdtable; cmdp->name; cmdp++)
- if(!strnicmp(cmdp->name,arg,arglen)) {
- if(cmdp->states & (1 << cp->type))
- (*cmdp->fnc)(cp);
- goto loop;
- }
- if(cp->type == CT_USER)
- cp->xmitted += usprintf(cp->fd,
- "*** Unknown command '/%s'. Type /? for help.\n",arg);
- goto loop;
- }
- if(isprint(*cp->ibuf) != 0 && cp->type == CT_USER)
- send_msg_to_channel(cp->name,cp->channel,cp->ibuf);
- }
- bye_command(cp);
- free_closed_connections();
- return;
- }
-
-
- #endif /* CHATNODE */
-